package jeecg.business.job;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;

import jeecg.business.entity.enter.EnterEntity;
import jeecg.business.entity.hot.HotKeyinfoEntity;
import jeecg.business.entity.keyinfo.KeyinfoEntity;
import jeecg.business.entity.keyinfo.KeyinfoTextEntity;
import jeecg.business.entity.keyword.KeywordEntity;
import jeecg.business.service.enter.EnterServiceI;
import jeecg.business.service.hot.HotKeyinfoServiceI;
import jeecg.business.service.keyinfo.KeyinfoServiceI;
import jeecg.business.service.keyinfo.KeyinfoTextServiceI;
import jeecg.business.service.keyword.KeywordServiceI;
import jeecg.business.vo.ContainWordNum;
import jeecg.business.vo.HotKeyInfoVo;
import jeecg.business.vo.WordNumComparator;
import jodd.util.StringUtil;

import org.jeecgframework.core.util.DataUtils;
import org.jeecgframework.core.util.wordseg.MmSegment;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

@Component
public class AnalysisTask {
	
	@Autowired
	EnterServiceI enterService;
	@Autowired
	KeyinfoServiceI keyinfoService;
	@Autowired
	KeyinfoTextServiceI textService;
	@Autowired
	KeywordServiceI keywordService;
	@Autowired
	HotKeyinfoServiceI hotService;
	/**
	 * 
	 * <p>
	 * 方法简要描述: 热点分析-使用KNN算法,根据所有词量的总数和概率
	 * </p>
	 * <p>
	 * 方法详细描述: // TODO
	 * </p>
	 * 
	 * @author LinYingPiaoJian(Q:71426052)
	 * @version 
	 * @see
	 */
	@Scheduled(cron="0 25 0/2 * * ?")
//	@Scheduled(cron="25 0/1 * * * ?")
	public void analysisHot(){
		List<EnterEntity> enterList = enterService.list();
		for(EnterEntity e : enterList){
			analysisHot(e);
		}
	}
	
	void analysisHot(EnterEntity enter){
		List<KeywordEntity> keywordList = keywordService.find(enter.getId());
		for(KeywordEntity kw : keywordList){
			analysisHot(enter , kw);
		}
	}
	
	void analysisHot(EnterEntity enter , KeywordEntity keyword){
		System.out.println("开始'"+enter.getName()+"-"+keyword.getKeyword()+"'的热点分析");
		Date starttime = DataUtils.getAddMonth(-1);
		Date sword = new Date();
		List<KeyinfoEntity> keyinfoList = keyinfoService.listByTime(enter.getId(),DataUtils.formatDate(starttime, "yyyy-MM-dd") , keyword.getKeyword());
		List<HotKeyInfoVo> volist = new ArrayList<HotKeyInfoVo>();
		if(keyinfoList != null){
			for(KeyinfoEntity k : keyinfoList)
				try {
					splitWord(k);
				} catch (Exception e) {
					e.printStackTrace();
				}
			HotKeyInfoVo v = null;
			boolean same = false;
			for(KeyinfoEntity k : keyinfoList){
				Date s = new Date();
				if(volist.size() == 0){
					v = new HotKeyInfoVo(k.getTitle() , k.getText().getContent() , k.getEventdate());
					v.addKeyinfo(k);
					volist.add(v);
				}else{
					/**
					 * 对比记录相似度
					 */
					for(HotKeyInfoVo vo : volist){
						same = false;
						if(compare(vo.getKeyinfoList(), k)){
							same = true;
							vo.addKeyinfo(k);
							break;
						}
					}
					if(same == false){
						v = new HotKeyInfoVo(k.getTitle() , k.getText().getContent() , k.getEventdate());
						v.addKeyinfo(k);
						volist.add(v);
					}
				}
//				System.out.println("位置："+(keyinfoList.indexOf(k)+1)+"-----用时："+(new Date().getTime()-s.getTime())/1000.0+"秒");
			}
			System.out.println("总计时："+(new Date().getTime()-sword.getTime())/1000.0+"秒");
			List<HotKeyinfoEntity> hotlist = new ArrayList<HotKeyinfoEntity>(); 
			HotKeyinfoEntity hot = null;
			KeyinfoEntity f = null;	//取第一个赋值
			for(HotKeyInfoVo vo : volist){
				String ids = null;
				hot = new HotKeyinfoEntity();
				if(vo.getKeyinfoList().size()>=3){		///大于等于3,说明是热点	
					f = vo.getKeyinfoList().get(0);
					Date btime = null;
					Date etime = null;
					for(KeyinfoEntity k : vo.getKeyinfoList()){
						if( ids == null) ids = k.getId();
						else ids += ","+k.getId();
						if(btime == null) btime = k.getEventdate();
						else if(btime.getTime()>=k.getEventdate().getTime()) btime = k.getEventdate();
						if(etime == null) etime = k.getEventdate();
						else if(etime.getTime()<=k.getEventdate().getTime()) etime = k.getEventdate();
					}
					hot.setTitle(f.getTitle());
					hot.setContent(f.getText().getContent());
					hot.setFmc(f.getFmc());
					hot.setFmccs(f.getFmccs());
					hot.setFmz(f.getFmz());
					hot.setFmcjb(f.getFmjb());
					hot.setRefword(f.getRefword());
					hot.setRefwordnum(f.getRefwordnum());
					hot.setRefids(ids);
					hot.setStarttime(btime);
					hot.setEndtime(etime);
					hot.setKeyword(f.getKeyword());
					hot.setAppeartime(vo.getKeyinfoList().size());
					hot.setQyid(f.getQyid());
					hotlist.add(hot);
//					System.out.println(vo.getTitle()+"-------------------次数："+vo.getKeyinfoList().size()+"--------------"+ids);
				}
			}
			hotService.save(enter.getId(), keyword.getKeyword(), hotlist);
		}
	}
	/**
	 * 
	 * <p>
	 * 方法简要描述: 对比相似度
	 * </p>
	 * <p>
	 * 方法详细描述: // TODO
	 * </p>
	 * 
	 * @author LinYingPiaoJian(Q:71426052)
	 * @version 
	 * @see
	 * @return
	 */
	boolean compare(List<KeyinfoEntity> keyinfoList , KeyinfoEntity keyinfo){
		boolean same = false;
		/**
		 * 词组数	---	差距1/5
		 */
		int wordNum = Math.abs(keyinfoList.get(0).getWordNumList().size()-keyinfo.getWordNumList().size());
		if(wordNum >= keyinfoList.get(0).getWordNumList().size()/5) return false;
		
		List<ContainWordNum> wnlist= keyinfo.getWordNumList();
		List<ContainWordNum> klist = null;
		int result = 0;
		int allnum = 0;	//总得次数
		int avgnum = 0;
		for(KeyinfoEntity k : keyinfoList){
			klist = k.getWordNumList();
			result += compare(wnlist, klist);
			for(ContainWordNum c : klist)
				allnum += c.getNum();
		}
		result = result/keyinfoList.size();
		avgnum = allnum/keyinfoList.size();
		if(result <= avgnum/5) same = true;		// 2 8 原则
		return same;
	}
	
	int compare(List<ContainWordNum> wnlist , List<ContainWordNum> klist){
		int result = 0;
		boolean has = false;
		for(ContainWordNum wn : wnlist){
			has = false;
			for(ContainWordNum k : klist){
				if(wn.getWord().equals(k.getWord())){
					has = true;
					result += Math.abs(wn.getNum() - k.getNum());
				}
			}
			if(has == false)
				result += wn.getNum();
		}
		return result;
	}
	
	int titleWeight = 3;
	int contentWeight = 1;
	/**
	 * 
	 * <p>
	 * 方法简要描述：分词
	 * </p>
	 * <p>
	 * 方法详细描述: // TODO
	 * </p>
	 * 
	 * @author LinYingPiaoJian(Q:71426052)
	 * @version 
	 * @see
	 * @param keyinfo
	 * @return
	 * @throws Exception
	 */
	KeyinfoEntity splitWord(KeyinfoEntity keyinfo) throws Exception{
		KeyinfoTextEntity text = textService.get(KeyinfoTextEntity.class, keyinfo.getId());
		keyinfo.setText(text);
		String title = keyinfo.getTitle();
		String content = text.getContent();
		List<String> titleList = null;
		List<String> contentList = null;
		if(StringUtil.isNotEmpty(title))
			titleList = MmSegment.segment(title);
		if(StringUtil.isNotEmpty(content))
			contentList = MmSegment.segment(content);
		
		List<ContainWordNum> wordNumList = new ArrayList<ContainWordNum>();
		ContainWordNum cwn = null;
		if(titleList != null){
			for(String tword : titleList){
				cwn = getBeanByWord(wordNumList, tword);
				if(cwn == null){
					cwn = new ContainWordNum(tword , titleWeight);
					wordNumList.add(cwn);
				}else{
					cwn.setNum(titleWeight+cwn.getNum());
				}
			}
		}
		
		if(contentList != null){
			for(String cword : contentList){
				cwn = getBeanByWord(wordNumList, cword);
				if(cwn == null){
					cwn = new ContainWordNum(cword , contentWeight);
					wordNumList.add(cwn);
				}else{
					cwn.setNum(contentWeight+cwn.getNum());
				}
			}
		}
		
		Collections.sort(wordNumList, new WordNumComparator());		
		
		keyinfo.setWordNumList(wordNumList);
		
		return keyinfo;
	}
	
	ContainWordNum getBeanByWord(List<ContainWordNum> wordNumList , String word){
		for(ContainWordNum wordnum : wordNumList){
			if(wordnum.getWord().equals(word))
				return wordnum;
		}
		return null;
	}
}
